package com.pronosticnews.client.admin.activity;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.pronosticnews.client.admin.ClientFactory;
import com.pronosticnews.client.admin.place.JourneePlace;
import com.pronosticnews.client.admin.view.listJournees.ListJourneesView;
import com.pronosticnews.client.admin.view.listJournees.ListJourneesView.Presenter;
import com.pronosticnews.client.event.InformationMessageEvent;
import com.pronosticnews.client.services.JourneeService;
import com.pronosticnews.client.services.JourneeServiceAsync;
import com.pronosticnews.client.services.ParticipationService;
import com.pronosticnews.client.services.ParticipationServiceAsync;
import com.pronosticnews.client.services.PartieService;
import com.pronosticnews.client.services.PartieServiceAsync;
import com.pronosticnews.client.util.InformationMessage;
import com.pronosticnews.client.util.InformationMessage.TYPE_MESSAGE;
import com.pronosticnews.shared.model.ClubDto;
import com.pronosticnews.shared.model.JourneeDto;
import com.pronosticnews.shared.model.ParticipationDto;
import com.pronosticnews.shared.model.PartieDto;
import com.pronosticnews.shared.model.SaisonDto;

import fr.ysa.services.config.ConfigRequetesDto;
import fr.ysa.services.config.FiltreDto;
import fr.ysa.services.config.FiltreDto.TYPE;
import fr.ysa.services.config.ValueFiltreDto;
import fr.ysa.services.config.ValueFiltreDto.OPERATION;

public class ListJourneesActivity extends AbstractActivity implements Presenter {

	private ListJourneesView view;

	private AsyncCallback<List<JourneeDto>> getListJourneesCallback;
	private JourneeServiceAsync journeeService;
	private ConfigRequetesDto configRequetesJournees;

	private AsyncCallback<List<ParticipationDto>> getListParticcipationCallback;
	private ParticipationServiceAsync participationService;
	private ConfigRequetesDto configRequetesParticipation;

	private AsyncCallback<List<PartieDto>> getListPartieCallback;
	private AsyncCallback<Collection<PartieDto>> savePartiesCallback;
	private PartieServiceAsync partieService;
	private ConfigRequetesDto configRequetesPartie;

	private PlaceController placeController;
	private com.google.web.bindery.event.shared.EventBus eventBus;

	private SaisonDto saison;


	public ListJourneesActivity(JourneePlace place, ClientFactory clientFactory) {
		eventBus = clientFactory.getEventBus();
		configRequetesJournees = new ConfigRequetesDto();
		view = clientFactory.getListJourneeView();
		view.setPresenter(this);
		placeController = clientFactory.getPlaceController();
		journeeService = GWT.create(JourneeService.class);
		participationService = GWT.create(ParticipationService.class);
		partieService = GWT.create(PartieService.class);

		saison = place.getSaison();
	}

	@Override
	public void start(AcceptsOneWidget container, EventBus eventBus) {
		getJournees();
		getClubs();
		container.setWidget(view.asWidget());
	}

	private void getClubs() {
		if (configRequetesParticipation == null) {
			configRequetesParticipation = new ConfigRequetesDto();
			FiltreDto filtreSaison = new FiltreDto();
			filtreSaison.setName(ParticipationDto.VALUE_NAME.saison.name());
			filtreSaison.setType(TYPE.OBJECT);
			ValueFiltreDto valueSaison = new ValueFiltreDto();
			valueSaison.setOperation(OPERATION.EQUAL);
			valueSaison.setValue(saison.getId().toString());
			filtreSaison.addValue(valueSaison);
			configRequetesParticipation.getFiltres().add(filtreSaison);
		}

		if (getListParticcipationCallback == null) {
			getListParticcipationCallback = new AsyncCallback<List<ParticipationDto>>() {

				@Override
				public void onSuccess(List<ParticipationDto> result) {
					List<ClubDto> clubs = new ArrayList<ClubDto>();
					ClubDto club = null;
					for (ParticipationDto particip : result) {
						club = particip.getClub();
						clubs.add(club);
					}
					view.setClubs(clubs);
				}

				@Override
				public void onFailure(Throwable caught) {
					InformationMessage erreur = new InformationMessage();
					List<String> messages = new ArrayList<String>();
					messages.add(caught.getMessage());
					erreur.setText(messages);
					erreur.setType(TYPE_MESSAGE.ERROR);
					eventBus.fireEvent(new InformationMessageEvent(erreur));
				}
			};
		}
		participationService.trouver(configRequetesParticipation,
				getListParticcipationCallback);

	}

	private void getJournees() {
		if (configRequetesJournees == null) {
			configRequetesJournees = new ConfigRequetesDto();
			FiltreDto filtreJournee = new FiltreDto();
			filtreJournee.setName(JourneeDto.VALUE_NAME.saison.name());
			filtreJournee.setType(TYPE.OBJECT);
			ValueFiltreDto valueChampionnat = new ValueFiltreDto();
			valueChampionnat.setOperation(OPERATION.EQUAL);
			valueChampionnat.setValue(saison.getId().toString());
			filtreJournee.addValue(valueChampionnat);
			configRequetesJournees.getFiltres().add(filtreJournee);
		}

		if (getListJourneesCallback == null) {
			getListJourneesCallback = new AsyncCallback<List<JourneeDto>>() {

				@Override
				public void onSuccess(List<JourneeDto> result) {
					view.setJournees(result);
				}

				@Override
				public void onFailure(Throwable caught) {
					InformationMessage erreur = new InformationMessage();
					List<String> messages = new ArrayList<String>();
					messages.add(caught.getMessage());
					erreur.setText(messages);
					erreur.setType(TYPE_MESSAGE.ERROR);
					eventBus.fireEvent(new InformationMessageEvent(erreur));
				}
			};
		}
		journeeService.trouver(configRequetesJournees, getListJourneesCallback);
	}

	@Override
	public void getParties(JourneeDto journee) {
		if (configRequetesPartie == null) {
			configRequetesPartie = new ConfigRequetesDto();
			FiltreDto filtreJournee = new FiltreDto();
			filtreJournee.setName(PartieDto.VALUE_NAME.journee.name());
			filtreJournee.setType(TYPE.OBJECT);
			ValueFiltreDto valueSaison = new ValueFiltreDto();
			valueSaison.setOperation(OPERATION.EQUAL);
			filtreJournee.addValue(valueSaison);
			configRequetesPartie.getFiltres().add(filtreJournee);
		}

		if (getListPartieCallback == null) {
			getListPartieCallback = new AsyncCallback<List<PartieDto>>() {

				@Override
				public void onSuccess(List<PartieDto> result) {

					view.setParties(result);
				}

				@Override
				public void onFailure(Throwable caught) {
					InformationMessage erreur = new InformationMessage();
					List<String> messages = new ArrayList<String>();
					messages.add(caught.getMessage());
					erreur.setText(messages);
					erreur.setType(TYPE_MESSAGE.ERROR);
					eventBus.fireEvent(new InformationMessageEvent(erreur));
				}
			};
		}
		configRequetesPartie.getFiltres().get(0).getValues().get(0).setValue(journee.getId().toString());
		partieService.trouver(configRequetesPartie, getListPartieCallback);
	}

	@Override
	public void updateParties(List<PartieDto> parties) {
		if (savePartiesCallback == null) {
			savePartiesCallback = new AsyncCallback<Collection<PartieDto>>() {
				
				@Override
				public void onSuccess(Collection<PartieDto> result) {
					InformationMessage messageSuccess = new InformationMessage();
					messageSuccess.setType(TYPE_MESSAGE.SUCCESS);
					List<String> messages = new ArrayList<String>();
					messages.add("Les matchs ont été mis à jour avec succès !");
					messageSuccess.setText(messages);
					eventBus.fireEvent(new InformationMessageEvent(
							messageSuccess));				
				}
				
				@Override
				public void onFailure(Throwable caught) {
					InformationMessage erreur = new InformationMessage();
					List<String> messages = new ArrayList<String>();
					messages.add(caught.getMessage());
					erreur.setText(messages);
					erreur.setType(TYPE_MESSAGE.ERROR);
					eventBus.fireEvent(new InformationMessageEvent(erreur));
				}
			};
		}
		partieService.sauvegarder(parties, savePartiesCallback);
	}
}
